package com.gzsxy.esjy.configuration;

import com.gzsxy.esjy.mapping.MappingInit;
import com.gzsxy.esjy.mapping.annotation.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * Bean拦截器
 * @RequestMapping路径映射注解生效的步骤：
 * 1.获取ApplicationContext上下文对象中所有被@Controller或@RequestMapping标识的bean
 * 2.遍历bean中的method，获取bean和method的RequestMappingInfo，将两个RequestMappingInfo整合，
 * 3.将得到RequestMappingInfo和对应的HandlerMethod存入Map中
 * 4.得到了对应的可执行method，那么什么时候调用呢，接下来看看下面的org.springframework.web.servlet.DispatcherServlet#doDispatch 当请求过来了做的分发
 *
 * 实现我们自定义的@RequestMapping只需要在bean初始化方法调用前将自定义的注解bean生效即可
 * @author zhangxiaolong
 * @date 2022/7/6 9:36
 */
public class NettyBeanProcesser implements BeanPostProcessor{
	
	private final static Logger log = LoggerFactory.getLogger(NettyBeanProcesser.class);
	
	@Autowired
	private MappingInit mappingInit ;

	/**
	 * bean初始化方法调用前被调用
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		Controller annotation = bean.getClass().getAnnotation(Controller.class);
		if(annotation != null) {
			try {
				//解析路径
				addMapping(bean, beanName);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}
		return bean;
	}

	/**
	 * bean初始化方法调用后被调用
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * 添加映射
	 */
	private void addMapping(Object bean,String beanName) throws Exception {
		mappingInit.addMapping(beanName, bean);
	}
}
